import os
import pathlib
from typing import IO, Any

__all__ = ["OutputManager"]


class OutputManager(object):
    """
    A class for managing outputs.

    For each input file, this project will generate a series of output files. The output files will be saved in a
    directory for distinguishment, whose name is conventionally the filename (without extension) of the input file.
    """

    _output_dir: pathlib.Path

    def __init__(self, output_dir: os.PathLike | str, input_filename: os.PathLike | str) -> None:
        """
        Initialize the output manager.

        This constructor will create a directory for the output files, whose name is the filename (without extension).

        Args:
            input_filename: The filename of the input file.
        """
        name = os.path.splitext(os.path.basename(input_filename))[0]
        output_dir = pathlib.Path(output_dir)
        self._output_dir = output_dir / name
        if not self._output_dir.exists():
            self._output_dir.mkdir(parents=True)

    def open(self, filename: os.PathLike | str, mode: str, encoding: str = "utf-8") -> IO[Any]:
        """
        Open a file in the output directory.

        This method will open a file in the output directory, and return the file object.

        Args:
            filename: The filename of the file to open.
            mode: The mode to open the file in.

        Returns:
            The file object.
        """
        path = self._output_dir / filename
        return path.open(mode, encoding=encoding)

    def filepath(self, filename: os.PathLike | str) -> pathlib.Path:
        """
        Get the path of a file in the output directory.

        This method will return the path of a file in the output directory, which is useful when you need to pass the
        path to other functions.

        Args:
            filename: The filename of the file to get the path of.

        Returns:
            The path of the file.
        """
        return self._output_dir / filename
